#ifndef VECTOR_H
#define VECTOR_H

#include "Types.h"
#include <iostream>

using namespace std;
/*
    vector.h -- declare Vector3, Matrix3, Real
 */
enum Axes{
    X_AXIS = 0,
    Y_AXIS,
    Z_AXIS,
    DIM
};

class Vector3
{
public:
    Real elts_[DIM];

    Real operator ()(int i) const { return elts_[i]; }
    Real& operator()(int i){ return elts_[i]; }
    Vector3();
    Vector3(Real x, Real y, Real z);
    Vector3(Real *);
    void Fill(Real);
    void Set(Real, Real, Real);

    static void ScalarMultiply(Vector3 &dest, Real s, Vector3 const& v);
    static void Add(Vector3 &dest, Vector3 const &w, Vector3 const& v);
    static void Sub(Vector3 &dest, Vector3 const &w, Vector3 const& v);

    static Real IP(Vector3 const&, Vector3 const&);
    static Real StaticLength2(Vector3 const&);
    static void Cross(Vector3 &, Vector3 const&, Vector3 const&);
    void Normalize();

    Vector3 operator - ()
    {
        Vector3 v(*this);
        v*=-1;
        return v;
    }
    Vector3& operator *= (Real r)
    {
        ScalarMultiply(*this, r, *this);
        return *this;
    }
    Vector3& operator /= (Real r)
    {
        return (*this) *= 1/r;
    }
    Vector3& operator += (Vector3 const &r)
    {
        Add(*this, r, *this);
        return *this;
    }
    Vector3& operator -= (Vector3 const &r)
    {
        Sub(*this, *this, r);
        return *this;
    }

	Real Length2() const{ return StaticLength2(*this); }
    Real Length() const;
    static Vector3 Cross(Vector3 v1, Vector3 v2);

};

Real EuclidianDistance (Vector3 const &,Vector3 const &);

Vector3 operator + (Vector3 v1, Vector3 const &v2);
Vector3 operator - (Vector3 v1, Vector3 const &v2);

Vector3 operator * (Real r, Vector3 v1);
Vector3 operator * ( Vector3 v1,Real r);

Real operator *(Vector3 const &v, Vector3 const& w);

inline Real Sqr (Real r)
{
  return r*r;
}



class ostream;
std::ostream &operator << (std::ostream&,Vector3 const &);

#endif // VECTOR_H
